package com.sceneworker.app;

import java.util.concurrent.Callable;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;

import com.jme.math.Vector3f;
import com.jme.scene.Spatial;
import com.jme.util.GameTaskQueueManager;
import com.jme2utils.objects.InputMode;
import com.jme2utils.staticutils.CameraUtils;
import com.sceneworker.app.globals.SceneWorkerDialogManager;
import com.sceneworker.app.globals.SceneWorkerGlobals;
import com.sceneworker.app.globals.SceneWorkerPreferencesPanel;
import com.sceneworker.app.globals.cacheobjects.TexturePainterCacheObject;
import com.sceneworker.app.help.HelpPanel;
import com.sceneworker.app.input.SceneWorkerInputHandler;
import com.sceneworker.editors.rotationeditor.RotatorPanel;
import com.sceneworker.editors.textureeditorlister.TextureListerPanel;
import com.sceneworker.util.swing.button.SimpleImageButton;
import com.sceneworker.util.swing.radiobutton.SimpleRadioButton;
import com.sceneworker.util.swing.radiobutton.SimpleRadioButtonManager;

/**
 * Tools palette for Scene Worker
 * @author noellynch
 *
 */
public class StandardJMEToolsPalette extends JPanel {

	public static final String SELECT_TRIS = "SelectTris";
	public static final String SCALE = "Scale";
	public static final String ROTATATION = "Rotatation";
	public static final String TRANSLATION = "Translation";
	public static final String FREE_TRANSLATION = "FreeTranslation";
	public static final String SPATIAL_SELECTION = "SpatialSelection";
	private		StandardJMEController		mcl_sceneWorker;
	private 	SimpleRadioButtonManager	mcl_mgr;
	
	public	StandardJMEToolsPalette(StandardJMEController cl_sceneWorker) {
		mcl_sceneWorker = cl_sceneWorker;
		
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		
		mcl_mgr = new SimpleRadioButtonManager();
		
		SimpleRadioButton         lcl_objSel = new SimpleRadioButton(SceneWorkerGlobals.DATA_DIR + "icons/objSel.png");
        lcl_objSel.setSelectionListener(new SimpleRadioButton.ISelectionListener() {
            public void handleSelection(SimpleRadioButtonManager cl_mgr) {
                GameTaskQueueManager.getManager().update(new Callable<Void>() {
                    public Void call() throws Exception {
                        mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kObjectSelection);
                        mcl_sceneWorker.getInputHandler().getSelectionHandler().setTriangleSelectMode(false);
                        mcl_sceneWorker.getInputHandler().getSelectionHandler().setTrianglePaintMode(false);
                        return null;
                    }
                });
            }
        });
        lcl_objSel.setToolTipText("Spatial Selection (q)");
        lcl_objSel.setName(SPATIAL_SELECTION);
		
		SimpleRadioButton			lcl_objFreeTx = new SimpleRadioButton(SceneWorkerGlobals.DATA_DIR + "icons/freeTxBtn.png");
		lcl_objFreeTx.setSelectionListener(new SimpleRadioButton.ISelectionListener() {
			public void handleSelection(SimpleRadioButtonManager cl_mgr) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kObjectFreeTranslation);
						return null;
					}
				});
			}
		});
		lcl_objFreeTx.setToolTipText("Free Translation In Plane Most Parallel To Camera (w)");
		lcl_objFreeTx.setName(FREE_TRANSLATION);
		
		SimpleRadioButton				lcl_txBtn = new SimpleRadioButton(SceneWorkerGlobals.DATA_DIR + "icons/Translate_Icon.png");
		lcl_txBtn.setSelectionListener(new SimpleRadioButton.ISelectionListener() {
			public void handleSelection(SimpleRadioButtonManager cl_mgr) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kObjectTranslationX);
						return null;
					}
				});
			}
		});
		lcl_txBtn.setToolTipText("Translate (e)");
		lcl_txBtn.setName(TRANSLATION);
		
		SimpleRadioButton				lcl_rotButton = new SimpleRadioButton(SceneWorkerGlobals.DATA_DIR + "icons/Rotate_Icon.png");
		lcl_rotButton.setSelectionListener(new SimpleRadioButton.ISelectionListener() {
			public void handleSelection(SimpleRadioButtonManager cl_mgr) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kObjectRotateY);
						return null;
					}
				});
			}
		});
		lcl_rotButton.setToolTipText("Rotate (r)");
		lcl_rotButton.setName(ROTATATION);
		
		SimpleRadioButton				lcl_scaleBtn = new SimpleRadioButton(SceneWorkerGlobals.DATA_DIR + "icons/Scale_Icon.png");
		lcl_scaleBtn.setSelectionListener(new SimpleRadioButton.ISelectionListener() {
			public void handleSelection(SimpleRadioButtonManager cl_mgr) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kObjectScaleX);
						return null;
					}
				});
			}
		});
		lcl_scaleBtn.setToolTipText("Scale (t)");
		lcl_scaleBtn.setName(SCALE);
		
		SimpleRadioButton       lcl_triPickerBtn = new SimpleRadioButton(SceneWorkerGlobals.DATA_DIR + "icons/Tri_Icon.png");
		lcl_triPickerBtn.setSelectionListener(new SimpleRadioButton.ISelectionListener() {
            public void handleSelection(SimpleRadioButtonManager cl_mgr) {
                GameTaskQueueManager.getManager().update(new Callable<Void>() {
                    public Void call() throws Exception {
                        mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kObjectSelection);
                        mcl_sceneWorker.getInputHandler().getSelectionHandler().setTriangleSelectMode(true);
                        mcl_sceneWorker.getInputHandler().getSelectionHandler().setTrianglePaintMode(false);
                        return null;
                    }
                });
                
            }
		});
		lcl_triPickerBtn.setToolTipText("Select Triangles in Currently Selected Spatial (y)");
		lcl_triPickerBtn.setName(SELECT_TRIS);
		
		SimpleRadioButton       lcl_textureList = new SimpleRadioButton(SceneWorkerGlobals.DATA_DIR + "icons/paint_brush.png");
		lcl_textureList.setSelectionListener(new SimpleRadioButton.ISelectionListener() {
            public void handleSelection(SimpleRadioButtonManager cl_mgr) {
				mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kTexturePaint);
				
				// no texture lister present
				TexturePainterCacheObject		lcl_co = (TexturePainterCacheObject)SceneWorkerGlobals.inst().getFromCache(TexturePainterCacheObject.TEXTURE_PAINTER);
				if(lcl_co == null) {
					JDialog		lcl_dlg = SceneWorkerDialogManager.inst().makeADialog(SceneWorkerDialogManager.TEXTURE_LIST);
					TextureListerPanel		lcl_tl = new TextureListerPanel(lcl_dlg);
					lcl_dlg.add(lcl_tl);
					lcl_dlg.setLocationRelativeTo(null);
					lcl_dlg.setVisible(true);
					
					lcl_co = new TexturePainterCacheObject(lcl_dlg, lcl_tl);
					SceneWorkerGlobals.inst().addToCache(lcl_co);
				}
				
				mcl_sceneWorker.getInputHandler().setInputHandlerMode(InputMode.kObjectSelection);
                mcl_sceneWorker.getInputHandler().getSelectionHandler().setTrianglePaintMode(true);
                mcl_sceneWorker.getInputHandler().getSelectionHandler().setTriangleSelectMode(true);
                
                if(mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection() instanceof Spatial) {
                	lcl_co.getTextureListerPanel().updateTextureList((Spatial)mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection());
                }
				
			}
		});
		
		SimpleImageButton				lcl_camTop = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/topCamBtn.png");
		lcl_camTop.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().setFocusOn(false);
						if(mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection() instanceof Spatial) {
							CameraUtils.doCameraPos((Spatial)mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection(), Vector3f.UNIT_Y, new Vector3f(0, 0, -1));
						}
						return null;
					}
				});
			}
		});
		lcl_camTop.setToolTipText("Camera Top");
		
		SimpleImageButton				lcl_camFront = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/frontCamBtn.png");
		lcl_camFront.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().setFocusOn(false);
						if(mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection() instanceof Spatial) {
							CameraUtils.doCameraPos((Spatial)mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection(), Vector3f.UNIT_Z, Vector3f.UNIT_Y);
						}
						return null;
					}
				});
			}
		});
		lcl_camFront.setToolTipText("Camera Front");
		
		SimpleImageButton				lcl_camLeft = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/leftCamBtn.png");
		lcl_camLeft.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().setFocusOn(false);
						if(mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection() instanceof Spatial) {
							CameraUtils.doCameraPos((Spatial)mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection(), new Vector3f(-1, 0, 0), Vector3f.UNIT_Y);
						}
						return null;
					}
				});
			}
		});
		lcl_camLeft.setToolTipText("Camera Left");
		
		SimpleImageButton				lcl_alignAlongX = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/alignX.png");
		lcl_alignAlongX.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().getSelectionHandler().alignAlongX();
						return null;
					}
				});
			}
		});
		lcl_alignAlongX.setToolTipText("Align Along X Axis");
		
		SimpleImageButton				lcl_alignAlongY = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/alignY.png");
		lcl_alignAlongY.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().getSelectionHandler().alignAlongY();
						return null;
					}
				});
			}
		});
		lcl_alignAlongY.setToolTipText("Align Along Y Axis");
		
		SimpleImageButton				lcl_alignAlongZ = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/alignZ.png");
		lcl_alignAlongZ.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().getSelectionHandler().alignAlongZ();
						return null;
					}
				});
			}
		});
		lcl_alignAlongZ.setToolTipText("Align Along Z Axis");
		
		SimpleImageButton				lcl_spaceX = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/spaceX.png");
		lcl_spaceX.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().getSelectionHandler().spaceAlongX();
						return null;
					}
				});
			}
		});
		lcl_spaceX.setToolTipText("Space Along Z Axis");
		
		SimpleImageButton				lcl_spaceY = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/spaceY.png");
		lcl_spaceY.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().getSelectionHandler().spaceAlongY();
						return null;
					}
				});
			}
		});
		lcl_spaceY.setToolTipText("Space Along Y Axis");
		
		SimpleImageButton				lcl_spaceZ = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/spaceZ.png");
		lcl_spaceZ.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					public Void call() throws Exception {
						mcl_sceneWorker.getInputHandler().getSelectionHandler().spaceAlongZ();
						return null;
					}
				});
			}
		});
		lcl_spaceZ.setToolTipText("Space Along Z Axis");
		
		SimpleImageButton			lcl_prefsBtn = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/preferences.png");
		lcl_prefsBtn.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				JDialog		lcl_dlg = SceneWorkerDialogManager.inst().makeADialog(SceneWorkerDialogManager.PREFERENCES_DIALOG);
				lcl_dlg.add(new SceneWorkerPreferencesPanel(lcl_dlg));
				lcl_dlg.setVisible(true);
			}
		});
		lcl_prefsBtn.setToolTipText("Preferences");
		
		SimpleImageButton			lcl_rotWorker = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/rotator.png");
		lcl_rotWorker.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				Object		lcl_sel = mcl_sceneWorker.getInputHandler().getSelectionHandler().getCurrentSelection();
				if(lcl_sel == null) { return; }
				
				if(lcl_sel instanceof Spatial) {
					JDialog		lcl_dlg = SceneWorkerDialogManager.inst().makeADialog(SceneWorkerDialogManager.ROTATOR_DIALOG);
					lcl_dlg.add(new RotatorPanel((Spatial)lcl_sel, lcl_dlg));
					lcl_dlg.setVisible(true);
				}
				
			}
		});
		lcl_rotWorker.setToolTipText("Rotation Dialog");
		
		SimpleImageButton			lcl_helpBtn = new SimpleImageButton(SceneWorkerGlobals.DATA_DIR + "icons/help_icon.png");
		lcl_helpBtn.setClickListener(new SimpleImageButton.IClickListener() {
			public void handleClick(SimpleImageButton e) {
				JDialog		lcl_dlg = SceneWorkerDialogManager.inst().makeADialog(SceneWorkerDialogManager.HELP);
				HelpPanel	lcl_help = new HelpPanel();
				lcl_dlg.add(lcl_help);
				lcl_dlg.setVisible(true);
			}
		});
		lcl_helpBtn.setToolTipText("Help");
		
		add(lcl_prefsBtn);
		add(Box.createHorizontalStrut(5));
		add(lcl_objSel);
		add(lcl_objFreeTx);
		add(lcl_txBtn);
		add(lcl_rotButton);
		add(lcl_scaleBtn);
		add(lcl_triPickerBtn);
		add(lcl_textureList);
		add(Box.createHorizontalStrut(5));
		add(lcl_rotWorker);
		add(Box.createHorizontalStrut(5));
		add(lcl_camFront);
		add(Box.createHorizontalStrut(2));
		add(lcl_camTop);
		add(Box.createHorizontalStrut(2));
		add(lcl_camLeft);
		add(Box.createHorizontalStrut(5));
		add(lcl_alignAlongX);
		add(Box.createHorizontalStrut(2));
		add(lcl_alignAlongY);
		add(Box.createHorizontalStrut(2));
		add(lcl_alignAlongZ);
		add(Box.createHorizontalStrut(5));
		add(lcl_spaceX);
		add(Box.createHorizontalStrut(2));
		add(lcl_spaceY);
		add(Box.createHorizontalStrut(2));
		add(lcl_spaceZ);
	    add(Box.createHorizontalStrut(2));
	    add(lcl_helpBtn);
	    
		mcl_mgr.addButton(lcl_objSel);
		mcl_mgr.addButton(lcl_objFreeTx);
		mcl_mgr.addButton(lcl_txBtn);
		mcl_mgr.addButton(lcl_rotButton);
		mcl_mgr.addButton(lcl_scaleBtn);
		mcl_mgr.addButton(lcl_triPickerBtn);
		mcl_mgr.addButton(lcl_textureList);
		mcl_mgr.setSelectionAt(0);
		
		setVisible(true);
	}
	
	public	SimpleRadioButtonManager		getTransformationButtonsManager() {
		return mcl_mgr;
	}
}

